package org.damazio.bhtranscams;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.content.Context;
import android.os.Handler;

/**
 * Logic for auto-updating the camera image.
 * 
 * @author rdamazio
 */
public class CameraAutoUpdater {
  private static final String AUTO_UPDATE_PREFERENCE_KEY = "org.damazio.bhtranscams.prefs.autoUpdate";
  private static final int AUTO_UPDATE_DELAY = 60 * 1000;  // 1 minute

  private final Activity context;
  private final Timer autoUpdateTimer;
  private final Handler autoUpdateHandler;
  private final Runnable updateRunnable;
  private boolean enabled;
  private TimerTask pendingUpdateTask;

  /**
   * Constructor.
   *
   * @param context the context for which to get/set preferences
   * @param updateRunnable the command to execute to actually do the update
   */
  public CameraAutoUpdater(Activity context, Runnable updateRunnable) {
    this.context = context;
    this.updateRunnable = updateRunnable;

    autoUpdateTimer = new Timer("bhtransCamsUpdate");
    autoUpdateHandler = new Handler();

    enabled = context.getPreferences(Context.MODE_PRIVATE)
        .getBoolean(AUTO_UPDATE_PREFERENCE_KEY, false);
  }

  /**
   * Schedules an update to happen in the future.
   * If an update was already scheduled, this is a no-op.
   */
  public void schedule() {
    if (enabled && pendingUpdateTask == null) {
      synchronized (autoUpdateTimer) {
        pendingUpdateTask = new TimerTask() {
          @Override
          public void run() {
            // Send the load request back to the UI thread
            autoUpdateHandler.post(updateRunnable);
  
            // Reset it so that nobody will call cancel on it after it's done
            pendingUpdateTask = null;
          }
        };
      }

      autoUpdateTimer.schedule(pendingUpdateTask, AUTO_UPDATE_DELAY);
    }
  }

  /**
   * Cancels any scheduled updates.
   * If there was no scheduled update, this is a no-op.
   */
  public void cancel() {
    if (enabled) {
      synchronized (autoUpdateTimer) {
        if (pendingUpdateTask != null) {
          pendingUpdateTask.cancel();
          pendingUpdateTask = null;
        }
      }
    }
  }

  /**
   * @return whether the auto-updating is enabled
   */
  public boolean isEnabled() {
    return enabled;
  }

  /**
   * Sets whether auto-updating should be enabled, and saves it to preferences.
   *
   * @param enabled whether auto-updating should be enabled
   */
  public void setEnabled(boolean enabled) {
    cancel();

    this.enabled = enabled;

    context.getPreferences(Context.MODE_PRIVATE)
        .edit()
        .putBoolean(AUTO_UPDATE_PREFERENCE_KEY, enabled)
        .commit();
  }
}
